﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.cruxomatic.configuration.FeatureManager;
using com.cruxomatic.configuration.PasswordManager;
using com.cruxomatic.DTOs.Configuration;
using com.cruxomatic.views.Administration;
using com.cruxomatic.BusinessFacades;
using com.cruxomatic.security.EncryptionAndHashing.Enums;
using com.cruxomatic.configuration;
using com.cruxomatic.logging;
using com.cruxomatic.logging.Enums;
using com.cruxomatic.DTOs;
using com.cruxomatic.exceptions;
using com.cruxomatic.security;

namespace com.cruxomatic.controllers.Administration
{
    public class ResetPasswordController
    {
        IResetPassword _view = null;
        public ResetPasswordController(IResetPassword view)
        {
            _view = view;
        }

        public void InitView(bool IsPostBack)
        {
            if (!IsPostBack)
            {
                CheckValidity();
            }
        }

        private void CheckValidity()
        {
            ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
            SessionData sessionData = new SessionData();
            UserFacade userFacade = new UserFacade();
            ForgotPasswordFacade facade = new ForgotPasswordFacade();
            UserInformation currentUser = (UserInformation)sessionData.CurrentUser;
            UserInformation userBeingModified = cruxSecurityManager.GetUser(_view.UserID);
            if (currentUser.UserID == _view.UserID)
                _view.EnableDisableControl = true;
            else
                _view.EnableDisableControl = false;
            if (sessionData.IsFirstTimeLogin && string.IsNullOrEmpty(userBeingModified.SecurityAnswer))
            {
                _view.EnableDisableControlForFirstTimer = true;
                _view.SecurityQuestionList = facade.GetAllSecurityQuestions();
            }
            else
                _view.EnableDisableControlForFirstTimer = false;
            
            if (!cruxSecurityManager.IsUserAuthorizedToChangePassword(currentUser, userBeingModified))
                NavigationController.OpenErrorPage("805");
        }

        public void ResetPassword()
        {
            bool success = false;
            if (PasswordConfirmationOk())
            {
                if (IsCurrentPasswordMatched())
                {
                    if (ValidatePasswordWithLastSavedPassword())
                    {
                        try
                        {
                            IPasswordManager passwordManager = PasswordManagerFactory.GetPasswordManager();
                            passwordManager.ValidatePassword(_view.NewPassword);
                            SaveNewPassword();
                            success = true;
                            SessionData data = new SessionData();
                            data.IsFirstTimeLogin = false;
                        }
                        catch (PasswordException ex)
                        {
                            _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError("103", ex.Message);
                        }
                        catch (Exception ex)
                        {
                            ApplicationLogger.LogApplicationMessage(
                                ex.Message, ApplicationLogType.Database, ex.StackTrace);
                            _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError("101", ex.Message);
                        }

                    }
                }
                else
                    _view.ErrorDetails = CruxConfigurationManager.GetErrorInformation("906");
            }
            else
                _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError("802");
            if (success) RedirectToRelevantView();
        }

        private bool ValidatePasswordWithLastSavedPassword()
        {
            IFeatureManager featureManager = FeatureManagerFactory.GetFeatureManager();
            if (featureManager.IsFeatureSupported("SavePreviousPasswords"))
            {
                int savedPasswordCount =
                Convert.ToInt32(CruxConfigurationManager.GetApplicationCustomSetting("NumberOfSavedPassword").Value);
                PasswordFacade facade = new PasswordFacade();
                PasswordStorageType passwordStorageType = CruxConfigurationManager.GetPasswordStorageType();
                if (facade.IsPasswordUsedBefore(_view.NewPassword, _view.UserID, passwordStorageType, savedPasswordCount))
                {
                    ErrorInformation error = CruxApplicationErrorManager.GetApplicationError("912");
                    error.ShortDescription = error.ShortDescription.Replace("{0}", Convert.ToString(savedPasswordCount));
                    error.ErrorDescription = error.ErrorDescription.Replace("{0}", Convert.ToString(savedPasswordCount));
                    error.RecommendedAction = error.RecommendedAction.Replace("{0}", Convert.ToString(savedPasswordCount));
                    error.ProbableCause = error.ProbableCause.Replace("{0}", Convert.ToString(savedPasswordCount));
                    _view.ErrorDetails = error;
                    return false;
                }
                else
                    return true;
            }
            else
                return true;
        }

        private bool IsCurrentPasswordMatched()
        {
            SessionData sessionData = new SessionData();
            UserInformation currentUser = (UserInformation)sessionData.CurrentUser;
            if (currentUser.UserID == _view.UserID)
            {
                ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
                if (cruxSecurityManager.AuthenticateUser(currentUser.UserName, _view.CurrentPassWord))
                    return true;
                else
                    return false;
            }
            else
                return true;
        }

        public void RedirectToRelevantView()
        {
            UserFacade facade = new UserFacade();
            UserInformation user = facade.GetUser(_view.UserID);
            SessionData sessionData = new SessionData();
            if (_view.UserID == sessionData.CurrentUser.UserID)
                NavigationController.OpenView("Administration");
            else
                NavigationController.OpenView("ManageUsers", user.CompanyID);

        }
        private void SaveNewPassword()
        {
            ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
            UserInformation userBeingModified = cruxSecurityManager.GetUser(_view.UserID);
            PasswordFacade passwordFacade = new PasswordFacade();
            PasswordStorageType passwordStorageType = CruxConfigurationManager.GetPasswordStorageType();
            IFeatureManager featureManager = FeatureManagerFactory.GetFeatureManager();
            bool isFeatureSupported = featureManager.IsFeatureSupported("SavePreviousPasswords");
            int savedPasswordCount = 
                Convert.ToInt32(CruxConfigurationManager.GetApplicationCustomSetting("NumberOfSavedPassword").Value);
            SessionData data = new SessionData();
            if(data.IsFirstTimeLogin && string.IsNullOrEmpty(userBeingModified.SecurityAnswer))
                passwordFacade.ResetPassword(_view.UserID, _view.NewPassword, passwordStorageType, _view.SelectedSecurityQuestionId, _view.Answer, savedPasswordCount, isFeatureSupported);
            else
                passwordFacade.ResetPassword(_view.UserID, _view.NewPassword, passwordStorageType, savedPasswordCount, isFeatureSupported);
        }

        private bool PasswordConfirmationOk()
        {
            if (_view.NewPassword != _view.ConfirmedNewPassword)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    }
}
